﻿#region Using

using System;
using System.Threading;

#endregion

namespace XNgine.Threading
{
    /// <summary>
    /// Provides the execution of some method in a separate thread,
    /// also the control over its execution and status notification events
    /// </summary>
    public class ThreadedExecutor
    {
        public delegate void ExecutionMethod(ThreadedExecutor exec);

        public ExecutionMethod Execution;

        public event EventHandler ExecutionFinished;
        public event EventHandler ExecutionStarted;
        public event EventHandler ExecutionPaused;
        public event EventHandler ExecutionResumed;
        public event EventHandler ExecutionAborted;

        private readonly ThreadStart threadStarter;
        private readonly Thread executionThread;

        private ThreadedExecutor()
        {
            threadStarter = delegate
                                {
                                    if (this.Execution != null)
                                        this.Execution(this);

                                    if (ExecutionFinished != null)
                                        ExecutionFinished(this, null);
                                };
            executionThread = new Thread(threadStarter);
        }

        public ThreadedExecutor(ExecutionMethod exec)
            : this()
        {
            this.Execution = exec;
        }

        public void StartLoading()
        {
            executionThread.Start();

            if (ExecutionStarted != null)
                ExecutionStarted(this, null);
        }

        public void PauseLoading()
        {
#pragma warning disable 618,612
            executionThread.Suspend();
#pragma warning restore 618,612

            if (ExecutionPaused != null)
                ExecutionPaused(this, null);
        }

        public void ResumeLoading()
        {
#pragma warning disable 618,612
            executionThread.Resume();
#pragma warning restore 618,612

            if (ExecutionResumed != null)
                ExecutionResumed(this, null);
        }

        public void AbortLoadnig()
        {
            executionThread.Abort();

            if (ExecutionAborted != null)
                ExecutionAborted(this, null);
        }
    }
}